/**
 * Chat client class
 * You need to call
 * CHAT_CLIENT = new ChatClient(<your var>)
 * prior to calling anything else
 * @author : Ecky Putrady
 */

/**
 * create a new chat client
 * myinfo : Javascript object
 *      - <int>     id      : user id
 *      - <string>  uname   : username
 *      - <string>  statmsg : status msg
 *      - <bool>    isOnline: is user online?
 * status_info : Javascript object
 *      - <string> available
 *      - <string> busy
 *      - <string> away
 */
function ChatClient(status_info, baseUrl) {

    interval = 2000;

    this.sendData = function(jsonstring, onConnOpenedF, onLoadingF, onLoadSuccessF, onLoadFailedF, addr) {
        ajWrap = new AjaxWrap();
        s = this.baseUrl + "chatserver" + (addr || "");
        ajWrap.chatClient = this;
        if(onConnOpenedF)   ajWrap.onConnectionOpened = onConnOpenedF;
        if(onLoadingF)      ajWrap.onLoading = onLoadingF;
        if(onLoadSuccessF)  ajWrap.onLoadSuccess = onLoadSuccessF;
        if(onLoadFailedF)   ajWrap.onLoadError = onLoadFailedF;
        ajWrap.openAndSend('POST', s, true, "data=" + encodeURIComponent(jsonstring));
    };

    this.sendDataNormal = function(jsonstring) {
        this.sendData(jsonstring, null, null, this.updateMe, null, null);
    };

    this.sendPeriodicRequest = function() {
        //CHAT_CLIENT.sendDataNormal("{}");
        CHAT_CLIENT.sendDataNormal(JSON.stringify({"send_msg":CHAT_CLIENT.chats_to_send}));
        CHAT_CLIENT.chats_to_send = [];
    };

    this.updateMe = function(ajWrap) {
        //alert(ajWrap.xhr.responseText);
        var server = JSON.parse(ajWrap.xhr.responseText);

        //Update interval
        CHAT_CLIENT.resetInterval();
        
        //Update followers
        var contacts = server.followers;
        var doc = document.getElementById("chat_followers_pane");
        for(key in contacts) {
            //Save it
            contacts[key].is_online = contacts[key].is_online && contacts[key].is_online != "0";
            CHAT_CLIENT.followers[contacts[key].user_id] = contacts[key];

            //Get the div
            var div = document.getElementById("chat_followers_" + contacts[key].user_id);
            if(div == null) {
                s = '<div ';
                s += 'id="chat_followers_' + contacts[key].user_id + '"';
                s += 'class="clickableitem"';
                s += 'onclick="chat_open_window(' + contacts[key].user_id +')"';
                s += '>'
                s += '</div>'
                doc.innerHTML += s;
            }
            div = document.getElementById("chat_followers_" + contacts[key].user_id);

            //Fill the div
            chat_status = CHAT_CLIENT.status_info[contacts[key].status];
            isonline = contacts[key].is_online && contacts[key].is_online != "0";
            s = '<div class="uname' + (isonline ? '' :  ' off') + '">' + contacts[key].username + '</div>';
            s += isonline ? '<img src="' + chat_status.icon_link + '" title="' + chat_status.name +'" />' : '';

            div.innerHTML = s;
        }

        //Update followees
        contacts = server.followees;
        doc = document.getElementById("chat_followees_pane");
        for(key in contacts) {
            //Save it
            contacts[key].isonline = contacts[key].is_online && contacts[key].is_online != "0";
            CHAT_CLIENT.followees[contacts[key].user_id] = contacts[key];

            //Get the div
            div = document.getElementById("chat_followees_" + contacts[key].user_id);
            if(div == null) {
                s = '<div ';
                s += 'id="chat_followees_' + contacts[key].user_id + '"';
                s += 'class="clickableitem"';
                s += 'onclick="chat_open_window(' + contacts[key].user_id +')"';
                s += '>'
                s += '</div>'
                doc.innerHTML += s;
            }
            div = document.getElementById("chat_followees_" + contacts[key].user_id);

            //Fill the div
            chat_status = CHAT_CLIENT.status_info[contacts[key].status];
            isonline = contacts[key].is_online && contacts[key].is_online != "0";
            s = '<div class="uname' + (isonline ? '' :  ' off') + '">' + contacts[key].username + '</div>';
            s += isonline ? '<img src="' + chat_status.icon_link + '" title="' + chat_status.name +'" />' : '';

            div.innerHTML = s;

            //update chat_windowbar
            chat_update_windowbar(contacts[key].user_id);
        }

        //Load chat cookies (only when just logged in)
        if(CHAT_CLIENT.justLoggedIn) {
            CHAT_CLIENT.justLoggedIn = false;
            cookie = getCookie(CHAT_CLIENT.cookie_name);
            parsed = cookie != null ? JSON.parse(cookie) : null;
            if(parsed && CHAT_CLIENT.my_info.user_id == parsed.my_info.user_id) {
                CHAT_CLIENT.chats = parsed.chats || [];

                //Show the chat
                for(key in CHAT_CLIENT.chats) {
                    msg = CHAT_CLIENT.chats[key];
                    elm = chat_open_window(msg.from_id != CHAT_CLIENT.my_info.user_id ? msg.from_id : msg.to_id).chat_content;
                    elm.innerHTML += chat_create_msg_content(msg);
                }
            }
        }

        //Update chat msgs
        new_msgs = server.new_msgs;
        if(new_msgs) {
            for(key in new_msgs) {
                msg = new_msgs[key];
                CHAT_CLIENT.chats.push(msg);
                elm = chat_open_window(msg.from_id != CHAT_CLIENT.my_info.user_id ? msg.from_id : msg.to_id).chat_content;
                elm.innerHTML += chat_create_msg_content(msg);
            }
        }

        //Save chat cookies
        setCookie(CHAT_CLIENT.cookie_name, JSON.stringify({"chats":CHAT_CLIENT.chats,"my_info":CHAT_CLIENT.my_info}));

    };

    this.resetInterval = function() {
        clearInterval(this.intervalId);
        this.intervalId = setInterval(this.sendPeriodicRequest, interval);
    };

    this.init = function(myinfo) {
        if(this.hasInit) return;
        this.hasInit = true;
        CHAT_CLIENT.my_info = myinfo;
        CHAT_CLIENT.my_info.is_online = CHAT_CLIENT.my_info.is_online == "0" ? 0 : CHAT_CLIENT.my_info.is_online;
        CHAT_CLIENT.updateMyInfo();
        if(!myinfo.is_online) {
            CHAT_CLIENT.shutDown();
            return;
        }
        CHAT_CLIENT.justLoggedIn = true;
        CHAT_CLIENT.sendDataNormal('{"justLogged":1}');
        CHAT_CLIENT.intervalId = setInterval(CHAT_CLIENT.sendPeriodicRequest, interval);
        
        //Set followers..
        document.getElementById("chat_followers_pane").innerHTML = "";
        document.getElementById("chat_followees_pane").innerHTML = "";

        //Set option pane
        div = document.getElementById("chat_options_pane_onlineoffline");
        div.innerHTML = '\
            <div class="clickableitem" onclick="CHAT_CLIENT.sendMyInfoUpdate(null, 0);">\
                Go offline\
            </div>';
        div = document.getElementById("chat_options_pane_status");
        div.style.display = "";
    };

    this.shutDown = function() {
        if(!this.hasInit) return;
        this.hasInit = false;
        clearInterval(this.intervalId);
        document.getElementById("chat_followers_pane").innerHTML = "You are offline";
        document.getElementById("chat_followees_pane").innerHTML = "You are offline";
        document.getElementById("cwcc").innerHTML = "";

        //Set option pane
        div = document.getElementById("chat_options_pane_onlineoffline");
        div.innerHTML = '\
            <div class="clickableitem" onclick="CHAT_CLIENT.sendMyInfoUpdate(null, 1);">\
                Go online\
            </div>';
        div = document.getElementById("chat_options_pane_status");
        div.style.display = "none";
    };

    this.sendMyInfoUpdate = function(status, isonline) {
        if(status != null)      this.my_info.status     = status;
        if(isonline != null)    this.my_info.is_online  = isonline;
        this.sendData(JSON.stringify(this.my_info), null, null, CHAT_CLIENT.myInfoUpdateHandler, null, "/userupdate");
    };

    this.myInfoUpdateHandler = function(ajWrap) {
        CHAT_CLIENT.my_info = JSON.parse(ajWrap.xhr.responseText);
        CHAT_CLIENT.my_info.is_online = CHAT_CLIENT.my_info.is_online == "0" ? 0 : CHAT_CLIENT.my_info.is_online;
        CHAT_CLIENT.updateMyInfo();
        if(!CHAT_CLIENT.my_info.is_online) CHAT_CLIENT.shutDown();
        else CHAT_CLIENT.init(CHAT_CLIENT.my_info);
    };

    this.updateMyInfo = function() {
        myinfo      = CHAT_CLIENT.my_info;
        chat_status = CHAT_CLIENT.status_info[myinfo.status];
        s = '<div class="uname' + (myinfo.is_online ? '' :  ' off') + '">' + myinfo.username + '</div>';
        s += myinfo.is_online ? '<img src="' + chat_status.icon_link + '" title="' + chat_status.name +'" />' : '';
        document.getElementById("chat_myinfo").innerHTML = s;
    };

    
    //////////// VARS ///////////////////////////////////////////////

    //Info about current user
    this.my_info = null;

    //Base URL information
    this.baseUrl = baseUrl;

    //Link to status info
    this.status_info = status_info;

    //List of users
    this.followers = new Array();
    this.followees = new Array();

    //All chat msgs
    this.chats          = [];
    this.chats_to_send  = [];

    //Cookie name
    this.cookie_name = "chat_syst_ecky_11";
    
    //Interval request
    this.intervalId = null;

    //Is new
    this.justLoggedIn = true;

    this.hasInit = false;

    return this;
}

/**
 * Remove chat window from container
 */
function chat_remove_window(chat_user_id) {
    div = chat_open_window(chat_user_id);
    doc = document.getElementById('cwcc');
    doc.removeChild(div.container);

    //Remove all msg from cookie that corresponds to that window
    for(i = 0; i < CHAT_CLIENT.chats.length; ++i) {
        msg = CHAT_CLIENT.chats[i];
        if(msg.from_id == chat_user_id || msg.to_id == chat_user_id) {
            CHAT_CLIENT.chats.splice(i, 1);
            --i;
        }
    }
}

/**
 * Open a chat window or create a new one
 * Then, return this window
 */
function chat_open_window(chat_user_id) {
    //Get user
    chat_user = chat_get_chat_user(chat_user_id);

    //Get the window
    cwid = "chat_window_" + chat_user_id;
    div = document.getElementById(cwid);
    if(div == null) { //Create a new one
        s = '<div class="chatwindowcontainer" id="cwc_' + chat_user_id + '">';
            s += '<div class="chatwindow"';
            s += 'id="' + cwid + '"';
            s += '>';
                s+= '<div class="chat_header">' + chat_user.username + '</div>';
                s+= '<div class="chat_content" id="chat_content_' + chat_user_id + '"></div>'
                s+= '   <div class="chat_input">    \
                            <input type="text" id="chat_input_' + chat_user_id + '" onkeypress="chat_on_input_keypress(event,' + chat_user_id + ')"/>   \
                        </div>';
            s += '</div>';
            s += '<div style="border-bottom:1px solid #aaaaaa;"></div>'
            s += '<div class="chatwindowbarcontainer" ';
            s += 'onclick="toggleVisibilityId(\'' + cwid + '\');"';
            s += '>';
                s += '<div class="chatwindowbar" id="chat_windowbar_' + chat_user_id +'">';
                s += '</div>';
                s += '<div class="chatwindowexit" onclick="chat_remove_window(' + chat_user_id +');"></div>'
            s += '</div>';
        s += '</div>';
        document.getElementById('cwcc').innerHTML += s;
        chat_update_windowbar(chat_user_id);
    }
    div = document.getElementById(cwid);
    if(div.style.display == 'none') toggleVisibility(div);

    return {
        "window" : div,
        "container" : document.getElementById("cwc_" + chat_user_id),
        "chat_content" : document.getElementById("chat_content_" + chat_user_id)
    };
}

function chat_on_input_keypress(e, chat_user_id) {
    e = e || window.event;
    var code = e.keyCode || e.which;
    if(code == 13) {
        var d = document.getElementById('chat_input_' + chat_user_id);
        if(d != "") chat_on_sendMsg(chat_user_id, d.value);
        d.value = "";
    }
}

function chat_on_sendMsg(chat_user_id, content) {
    data = new Object();
    data.to_id      = chat_user_id;
    data.content    = content;

    CHAT_CLIENT.chats_to_send.push(data);
    //CHAT_CLIENT.sendDataNormal(JSON.stringify({"send_msg":[data]}));
}

function chat_create_msg_content(msg) {
    chat_user = chat_get_chat_user(msg.from_id);

    s = '<div class="chat_msg">'
    s += '<div class="chat_msg_time">' + msg.timestamp + '</div>';
    s += '<div class="chat_msg_sender">' + chat_user.username + '</div>';
    s += '<div class="chat_msg_content">' + msg.content + '</div>';
    s += '</div>'

    return s;
}

function chat_update_windowbar(chat_user_id) {
    div = document.getElementById('chat_windowbar_' + chat_user_id);
    if(div == null) return;

    chat_user = chat_get_chat_user(chat_user_id);
    s = '<div style="display:inline-block;' + (chat_user.is_online ? '' : 'color:#888888;') +'">' + chat_user.username + '</div>';
    chat_status = CHAT_CLIENT.status_info[chat_user.status];
    s += chat_user.is_online ? '<img src="' + chat_status.icon_link + '" title="' + chat_status.name +'" style="float:left; margin:-2px auto;"/>' : '';
    div.innerHTML = s;
}

function chat_get_chat_user(id) {
    if(CHAT_CLIENT.my_info.user_id == id) return CHAT_CLIENT.my_info;
    else return CHAT_CLIENT.followers[id] || CHAT_CLIENT.followees[id];
}